﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using WIKID.Controller;
using WIKID.Model;
using WIKID.Common;
using System.Globalization;

namespace WIKID.View
{
    public partial class ChartView : UserControl
    {
        private ParentController parentController;
        public ChartView()
        {
            InitializeComponent();
            parentController = new ParentController();
        }
        /// <summary>
        /// Load the Chart View Method
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ChartView_Load(object sender, EventArgs e)
        {
            if (!DesignMode)
            {
                Dictionary<int, string> dicAccounts = parentController.ListingAccounts();
                cbAccounts.Items.Add(Constants.THERE_NO_ACCOUNT);
                if (dicAccounts.Count != 0)
                {
                    cbAccounts.DataSource = new BindingSource(dicAccounts, null);
                    cbAccounts.DisplayMember = "Value";
                    cbAccounts.ValueMember = "Key";
                }
                cbAccounts.SelectedItem = cbAccounts.Items[0];
                cbChartType.DataSource = Constants.CHART_TYPES;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbAccounts_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbAccounts.SelectedValue != null && !cbAccounts.SelectedValue.ToString().Equals(Constants.THERE_NO_ACCOUNT))
            {
                KeyValuePair<int, string> account = (KeyValuePair<int, string>)cbAccounts.SelectedItem;
                string fileName = account.Key + Constants.SEPARATE_CHAR + account.Value;
                AccountModel accountModel = parentController.GetAccountModel(fileName);
                DrawWeeklySeries(accountModel);
                DrawMonthlySeries(accountModel);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="accountModel"></param>
        private void DrawWeeklySeries(AccountModel accountModel)
        {
            DateTime weekStartDate, weekEndDate, dtNow = DateTime.Now;
            weekStartDate = GetFirstDayOfWeek(dtNow);
            weekEndDate = weekStartDate.AddDays(6);
   
            chart1.Series[0].Points.Clear();
            chart1.Series[1].Points.Clear();
            chart1.Titles[0].Text = "Week (" + weekStartDate.ToString("dd/MM") + " - " + weekEndDate.ToString("dd/MM") + ") Chart";
            List<ScoreModel> lsScoreModel = new List<ScoreModel>();
            lsScoreModel = parentController.GetWeeklyScores(accountModel);
            DataPoint datapoint;
            foreach (ScoreModel scoreModel in lsScoreModel)
            {
                datapoint = new DataPoint(Convert.ToDouble(scoreModel.LectureId), Convert.ToDouble(scoreModel.StudyingScore));
                chart1.Series[0].Points.Add(datapoint);
                datapoint = new DataPoint(Convert.ToDouble(scoreModel.LectureId), Convert.ToDouble(scoreModel.AttitudeScore));
                chart1.Series[1].Points.Add(datapoint);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="accountModel"></param>
        private void DrawMonthlySeries(AccountModel accountModel)
        {
            chart1.Series[2].Points.Clear();
            chart1.Series[3].Points.Clear();
            List<ScoreModel> lsScoreModel = new List<ScoreModel>();
            lsScoreModel = parentController.GetMonthlyScores(accountModel);
            DataPoint datapoint;
            foreach (ScoreModel scoreModel in lsScoreModel)
            {
                datapoint = new DataPoint(Convert.ToDouble(scoreModel.LectureId), Convert.ToDouble(scoreModel.StudyingScore));
                chart1.Series[2].Points.Add(datapoint);
                datapoint = new DataPoint(Convert.ToDouble(scoreModel.LectureId), Convert.ToDouble(scoreModel.AttitudeScore));
                chart1.Series[3].Points.Add(datapoint);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbChartType_SelectedIndexChanged(object sender, EventArgs e)
        {
            string chartType = cbChartType.SelectedValue.ToString();
            if (chartType.Equals(Constants.CHART_TYPES[0]))
            {
                chart1.Series[0].ChartType = SeriesChartType.Column;
                chart1.Series[1].ChartType = SeriesChartType.Column;
                chart1.Series[2].ChartType = SeriesChartType.Column;
                chart1.Series[3].ChartType = SeriesChartType.Column;
            }
            else if (chartType.Equals(Constants.CHART_TYPES[1]))
            {
                chart1.Series[0].ChartType = SeriesChartType.Line;
                chart1.Series[1].ChartType = SeriesChartType.Line;
                chart1.Series[2].ChartType = SeriesChartType.Line;
                chart1.Series[3].ChartType = SeriesChartType.Line;
            }
        }

        /// <summary>
        /// Returns the last day of the week that the specified
        /// date is in using the current culture.
        /// </summary>
        /// <param name="dayInWeek"></param>
        /// <returns></returns>
        private DateTime GetLastDayOfWeek(DateTime dayInWeek)
        {
            CultureInfo defaultCultureInfo = CultureInfo.CurrentCulture;
            return GetLastDayOfWeek(dayInWeek, defaultCultureInfo);
        }

        /// <summary>
        /// Returns the last day of the week that the specified date is in.
        /// </summary>
        /// <param name="dayInWeek"></param>
        /// <param name="cultureInfo"></param>
        /// <returns></returns>
        private DateTime GetLastDayOfWeek(DateTime dayInWeek, CultureInfo cultureInfo)
        {
            DayOfWeek lastDay = cultureInfo.DateTimeFormat.FirstDayOfWeek;
            DateTime lastDayInWeek = dayInWeek.Date;
            while (lastDayInWeek.DayOfWeek != lastDay)
                lastDayInWeek = lastDayInWeek.AddDays(6);
            return lastDayInWeek;
        }

        /// <summary>
        /// Returns the first day of the week that the specified
        /// date is in using the current culture.
        /// </summary>
        /// <param name="dayInWeek"></param>
        /// <returns></returns>
        private DateTime GetFirstDayOfWeek(DateTime dayInWeek)
        {
            CultureInfo defaultCultureInfo = CultureInfo.CurrentCulture;
            return GetFirstDayOfWeek(dayInWeek, defaultCultureInfo);
        }

        /// <summary>
        /// Returns the first day of the week that the specified date is in.
        /// </summary>
        /// <param name="dayInWeek"></param>
        /// <param name="cultureInfo"></param>
        /// <returns></returns>
        private DateTime GetFirstDayOfWeek(DateTime dayInWeek, CultureInfo cultureInfo)
        {
            DayOfWeek firstDay = cultureInfo.DateTimeFormat.FirstDayOfWeek;
            DateTime firstDayInWeek = dayInWeek.Date;
            while (firstDayInWeek.DayOfWeek != firstDay)
                firstDayInWeek = firstDayInWeek.AddDays(-1);
            return firstDayInWeek;
        }
    }
}
